from widget import BasicLayout
import view



class VerticalLayout(BasicLayout):

    def __init__(self, *args, **kwargs):
        self._heightlist = []
        BasicLayout.__init__(self, *args, **kwargs)


    def update_height(self):


        if self.height != self._heightlist[-1]:

            for nmb, child in enumerate(self.children):
                if self._heightlist[nmb] != child.height:
                    break

            if self.ystick == 'bottom':

                if nmb == 0:
                    self.children[0].bottom = self.bottom
                    nmb = 1

                for child in self.children[nmb:]:

                    self._heightlist[nmb] = child.height
                    child.bottom = self.children[nmb-1].top

                self.height = (self.children[-1].top - 
                               self.children[0].bottom)
                self._heightlist[-1] = self.height


            elif self.ystick == 'top':

                if nmb == 0:
                    self.children[0].top = self.top
                    nmb = 1

                for child in self.children[nmb:]:

                    self._heightlist[nmb] = child.height
                    child.top = self.children[nmb-1].bottom

                self.height = (self.children[0].top -
                               self.children[-1].bottom)
                self._heightlist[-1] = self.height



    def update_width(self):

        width = 0
        for child in self.children:

            if child.width > width:
                width = child.width

        if self.width < width:
            self.width = width
            
            if self.xstick == 'left':
                for child in self.children:
                    child.left = self.left

            elif self.xstick == 'right':
                for child in self.children:
                    child.right = self.right



    def add_child(self, child):
        BasicLayout.add_child(self, child)
        
        self._heightlist.insert(-2, child.height)
        self._heightlist[-1] += child.height

        self.update_width()
        self.update_height()


    def remove_child(self, child=None, nmb=None):
        
        if not nmb:
            nmb = self.children.index(child)
        elif not child:
            child = self.children[nmb]

        del self._heightlist[nmb]
        self._heightlist[-1] -= child.height
        BasicLayout.remove_child(child, nmb)

        self.update_width()
        self.update_height()


    def insert_child(self, nmb, child):
        BasicLayout.insert_child(nmb, child)

        self._heightlist.insert(nmb, child.height)
        self._heightlist[-1] += child.height

        self.update_width()
        self.update_height()


    def draw(self, rect=None):
        self.update_height()
        self.update_width()

        BasicLayout.draw(self, rect)



class HorizontalLayout(BasicLayout):

    def __init__(self, *args, **kwargs):
        self._widthlist = []
        BasicLayout.__init__(self, *args, **kwargs)


    def update_width(self):


        if self.width != self._widthlist[-1]:

            for nmb, child in enumerate(self.children):
                if self._widthlist[nmb] != child.width:
                    break

            if self.xstick == 'left':

                if nmb == 0:
                    self.children[0].left = self.left
                    nmb = 1

                for child in self.children[nmb:]:

                    self._widthlist[nmb] = child.width
                    child.left = self.children[nmb-1].right

                self.width = (self.children[-1].right - 
                              self.children[0].left)
                self._widthlist[-1] = self.width


            elif self.xstick == 'right':

                if nmb == 0:
                    self.children[0].right = self.right
                    nmb = 1

                for child in self.children[nmb:]:

                    self._widthlist[nmb] = child.width
                    child.right = self.children[nmb-1].left

                self.width = (self.children[0].right -
                              self.children[-1].left)
                self._widthlist[-1] = self.width



    def update_height(self):

        height = 0
        for child in self.children:

            if child.height > height:
                height = child.height

        if self.height < height:
            self.height = height
            
            if self.ystick == 'bottom':
                for child in self.children:
                    child.bottom = self.bottom

            elif self.ystick == 'top':
                for child in self.children:
                    child.top = self.top



    def add_child(self, child):
        BasicLayout.add_child(self, child)
        
        self._widthlist.insert(-2, child.width)
        self._widthlist[-1] += child.width
        
        self.update_height()
        self.update_width()


    def remove_child(self, child=None, nmb=None):
        
        if not nmb:
            nmb = self.children.index(child)
        elif not child:
            child = self.children[nmb]

        del self._widthlist[nmb]
        self._widthlist[-1] -= child.width
        BasicLayout.remove_child(child, nmb)

        self.update_height()
        self.update_width()


    def insert_child(self, nmb, child):
        BasicLayout.insert_child(nmb, child)

        self._widthlist.insert(nmb, child.width)
        self._widthlist[-1] += child.width

        self.update_height()
        self.update_width()


    def draw(self, rect=None):
        self.update_width()
        self.update_height()

        BasicLayout.draw(self, rect)



class FlowLayout(BasicLayout):

    def __init__(self, *args, **kwargs):
        self.modified = False
        
        BasicLayout.__init__(self, *args, **kwargs)
        self.register_fg(view.BeveledInlay)



    def _organize_rows(self):

        self._rows = [[]]
        width = 0

        for child in self.children:
            width += child.width

            if width <= self.width:
                self._rows[-1].append(child)

            elif width > self.width:
                self._rows.append([])
                width = 0

                if len(self._rows[-2]) == 0:
                    self._rows[-2].append(child)

                else:
                    self._rows[-1].append(child)
                    width = child.width

        

    def _resize_routine(self):
        self._organize_rows()

        top = self.top
        for row in self._rows:
            
            width = 0
            height = 0
            
            for col in row:
                width += col.width
                
                if col.height > height:
                    height = col.height

            width = self.width - width
            width = int(width / float(len(row) + 1))

            left = self.left
            for col in row:

                left += width
                col.left = left
                left += col.width
                col.top = top

            top -= height


    def add_child(self, child):
        BasicLayout.add_child(self, child)
        self._modified = True

    def remove_child(self, child=None, nmb=None):
        BasicLayout.remove_child(child, nmb)
        self._modified = True


    def draw(self, rect=None):
        if self._modified:

            self._modified = False
            self._resize_routine()

        BasicLayout.draw(self, rect)



class CardLayout(BasicLayout):

    def __init__(self, *args, **kwargs):
        BasicLayout.__init__(self, *args, **kwargs)
        self._active_nmb = 0
        self._modified = True


    @property
    def child(self):
        if self.children:
            return self.children[self._active_nmb] - 1

    def next(self):
        self._active_nmb += 1
        if self._active_child >= len(self.children):
            self._active_nmb = 0
        self._modified = True

    def previouse(self):
        self._active_nmb -= 1
        if self._active_nmb < 0:
            self._active_nmb = len(self.children) - 1
        self._modified = True

    def first(self):
        self._active_nmb = 0
        self._modified = True

    def last(self):
        self._active_nmb = len(self.children) - 1
        self._modified = True

    def show(self, nmb):
        if nmb > -1 and nmb < len(self.children[-1]):
            self._active_nmb = nmb
        self._modified = True

    def draw(self, rect=None):
        
        if self._modified and self.child:
            self._modified = False

            if self.xstick == 'left':
                self.child.left = self.left
            else:
                self.child.right = self.right

            if self.ystick == 'top':
                self.child.top = self.top
            else:
                self.child.bottom = self.bottom

            self.width = self.child.width
            self.height = self.child.height


        if rect:

            rect = self.clip(rect)
            self._draw_background(rect)
            self.child.draw(rect)
            self._draw_foreground(rect)

        else:

            self._draw_background()
            self.child.draw(self)
            self._draw_foreground()
